using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Universal.Application.Repositories;
using System.Security.Claims;

namespace Universal.Api.Attributes;

/// <summary>
/// 权限检查特性
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class RequirePermissionAttribute : Attribute, IAsyncAuthorizationFilter
{
    private readonly string _permissionCode;

    public RequirePermissionAttribute(string permissionCode)
    {
        _permissionCode = permissionCode;
    }

    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        Console.WriteLine($"[RequirePermission] 开始检查权限: {_permissionCode}");

        // 获取权限服务
        var permissionService = context.HttpContext.RequestServices.GetRequiredService<IPermissionService>();

        // 获取用户ID - 优先从HttpContext获取
        var userId = context.HttpContext.Items["UserId"] as Guid?;
        Console.WriteLine($"[RequirePermission] 从HttpContext获取的用户ID: {userId}");

        if (!userId.HasValue)
        {
            // 如果HttpContext中没有，尝试从JWT token中获取 - 尝试多种claim名称
            var subClaim = context.HttpContext.User.FindFirst("sub") ??
                          context.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier) ??
                          context.HttpContext.User.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier");

            Console.WriteLine($"[RequirePermission] 从JWT获取的claim: {subClaim?.Type} = {subClaim?.Value}");

            if (subClaim != null && Guid.TryParse(subClaim.Value, out var uid))
            {
                userId = uid;
                Console.WriteLine($"[RequirePermission] 从JWT解析的用户ID: {userId}");
            }
            else
            {
                Console.WriteLine("[RequirePermission] 无法获取用户ID，返回401");
                context.Result = new UnauthorizedObjectResult(new
                {
                    code = 401,
                    message = "未授权访问"
                });
                return;
            }
        }

        // 检查用户是否有指定权限
        Console.WriteLine($"[RequirePermission] 开始检查用户 {userId} 的权限 {_permissionCode}");
        var hasPermission = await permissionService.HasPermissionAsync(userId.Value, _permissionCode);
        Console.WriteLine($"[RequirePermission] 权限检查结果: {hasPermission}");

        if (!hasPermission)
        {
            Console.WriteLine($"[RequirePermission] 权限检查失败，返回403");
            context.Result = new ForbidObjectResult(new
            {
                code = 403,
                message = "无该权限"
            });
            return;
        }

        Console.WriteLine($"[RequirePermission] 权限检查通过");
    }
}

/// <summary>
/// 自定义Forbid结果
/// </summary>
public class ForbidObjectResult : ObjectResult
{
    public ForbidObjectResult(object value) : base(value)
    {
        StatusCode = 403;
    }
}
